import ply.yacc as yacc
from lex_csh import tokens
from parser_xml import *

lista_enum=[]
Parser_csh = MiParser()
codigo=''
def tupla_p(p):
    lista=[]
    string=''
    for elemento in range(0,len(p)):
        if p[elemento] != None:
            lista.append(p[elemento])

    for elemento in lista:
        #Se agrega el espacio para que los token se encuentren siempre separados por un espacio
        string=string+str(elemento)+' '

    #Se quita el ultimo espacio
    return string.strip(' ')

#___A.2.1 Basic Concepts______________________________________________________________#

def p_e_compilation_unit(p):
    '''compilation_unit : opcional_extern_alias_directives opcional_using_directives opcional_global_attributes opcional_namespace_member_declarations'''
    pass


def p_e_opcional_extern_alias_directives(p):
    '''opcional_extern_alias_directives : extern_alias_directives
                                        | '''
    pass

def p_e_opcional_using_directives(p):
    '''opcional_using_directives : using_directives
                                        | '''
    pass

def p_e_opcional_global_attributes(p):
    '''opcional_global_attributes : global_attributes
                                        | '''
    pass

def p_e_opcional_namespace_member_declarations(p):
    '''opcional_namespace_member_declarations : namespace_member_declarations
                                        | '''
    pass

def p_e_type_name(p):
    '''type_name : simple_name
                | qualified_alias_member
                | type_name PUNTO ID type_argument_list
                | type_name PUNTO ID'''
    p[0]=tupla_p(p)

#___A.2.2 Types______________________________________________________________#

def p_e_type(p):
    '''type : type_name
                    | simple_type
                    | OBJECT
                    | STRING
                    | array_type
                    | pointer_type
                    | VOID'''
    p[0]=tupla_p(p)

def p_e_simple_type(p):
    '''simple_type : numeric_type
                    | BOOL'''
    p[0]=tupla_p(p)

def p_e_numeric_type(p):
    '''numeric_type : integral_type
                    | floating_point_type
                    | DECIMAL'''
    p[0]=tupla_p(p)

def p_e_integral_type(p):
    '''integral_type : SBYTE
                    | BYTE
                    | SHORT
                    | USHORT
                    | INT
                    | UINT
                    | LONG
                    | ULONG
                    | CHAR'''
    p[0]=tupla_p(p)

def p_e_floating_point_type(p):
    '''floating_point_type : FLOAT
                    | DOUBLE'''
    p[0]=tupla_p(p)

def p_e_array_type(p):
    '''array_type : type rank_specifiers
                    | ID rank_specifiers'''
    p[0]=tupla_p(p)

def p_e_rank_specifiers(p):
    '''rank_specifiers : rank_specifier
                    | rank_specifiers rank_specifier'''
    p[0]=tupla_p(p)

def p_e_rank_specifier(p):
    '''rank_specifier : ABRE_CORCHETE opcional_dim_separators CIERRA_CORCHETE'''
    p[0]=tupla_p(p)

def p_e_opcional_dim_separators(p):
    '''opcional_dim_separators : dim_separators
                    | '''
    pass

def p_e_dim_separators(p):
    '''dim_separators : COMA
                    | dim_separators COMA'''
    pass

#___A.2.3 Variables______________________________________________________________#

def p_e_variable_reference(p):
    '''variable_reference : expression'''
    pass

#___A.2.4 Expressions______________________________________________________________#

def p_e_argument_list(p):
    '''argument_list : argument
                    | argument_list COMA argument'''
    pass

def p_e_argument(p):
    '''argument : expression
                    | REF variable_reference
                    | OUT variable_reference'''
    pass

def p_e_primary_expression(p):
    '''primary_expression : array_creation_expression
                    | primary_no_array_creation_expression'''
    pass

# primary_expression deberia incluir las reglas ID type_argument_list y ID por medio de primary_no_array_creation_expression. Ver si esto trae problemas

def p_e_primary_no_array_creation_expression(p):
    '''primary_no_array_creation_expression : literal
                    | parenthesized_expression
                    | member_access
                    | invocation_expression
                    | element_access
                    | this_access
                    | base_access
                    | post_increment_expression
                    | post_decrement_expression
                    | object_creation_expression
                    | delegate_creation_expression
                    | typeof_expression
                    | checked_expression
                    | unchecked_expression
                    | default_value_expression
                    | anonymous_method_expression
                    | sizeof_expression
                    | pointer_member_access
                    | pointer_element_access'''
    pass

def p_e_simple_name(p):
    '''simple_name : ID type_argument_list
                    | ID'''
    p[0]=tupla_p(p)

def p_e_parenthesized_expression(p):
    '''parenthesized_expression : ABRE_PARENTESIS expression CIERRA_PARENTESIS'''
    pass

def p_e_member_access(p):
    '''member_access : primary_expression PUNTO ID type_argument_list
                    | primary_expression PUNTO ID
                    | predefined_type PUNTO type_argument_list
                    | predefined_type PUNTO
                    | qualified_alias_member PUNTO ID type_argument_list
                    | qualified_alias_member PUNTO ID'''



def p_e_predefined_type(p):
    '''predefined_type : BOOL
                    | BYTE
                    | CHAR
                    | DECIMAL
                    | DOUBLE
                    | FLOAT
                    | INT
                    | LONG
                    | OBJECT
                    | SBYTE
                    | SHORT
                    | STRING
                    | UINT
                    | ULONG
                    | USHORT'''
    pass

def p_e_invocation_expression(p):
    '''invocation_expression : primary_expression ABRE_PARENTESIS argument_list CIERRA_PARENTESIS
                            | primary_expression ABRE_PARENTESIS CIERRA_PARENTESIS'''
    pass

def p_e_element_access(p):
    '''element_access : primary_no_array_creation_expression ABRE_CORCHETE expression_list CIERRA_CORCHETE
                    | ID type_argument_list ABRE_CORCHETE expression_list CIERRA_CORCHETE
                    | ID ABRE_CORCHETE expression_list CIERRA_CORCHETE'''
    pass

def p_e_expression_list(p):
    '''expression_list : expression
                    | expression_list COMA expression'''
    pass

def p_e_this_access(p):
    '''this_access : THIS'''
    pass

def p_e_base_access(p):
    '''base_access : BASE PUNTO ID type_argument_list
                    | BASE PUNTO ID
                    | BASE ABRE_CORCHETE expression_list CIERRA_CORCHETE'''
    pass



def p_e_post_increment_expression(p):
    '''post_increment_expression : primary_expression INCREMENTAL'''
    pass

def p_e_post_decrement_expression(p):
    '''post_decrement_expression : primary_expression DECREMENTAL'''
    pass

def p_e_object_creation_expression(p):

    '''object_creation_expression : NEW type ABRE_PARENTESIS argument_list CIERRA_PARENTESIS
                                    | NEW type ABRE_PARENTESIS CIERRA_PARENTESIS'''
    pass



def p_e_array_creation_expression(p):
    '''array_creation_expression : NEW type ABRE_CORCHETE expression_list CIERRA_CORCHETE rank_specifiers array_initializer
                                | NEW ID ABRE_CORCHETE expression_list CIERRA_CORCHETE rank_specifiers array_initializer
                                | NEW type ABRE_CORCHETE expression_list CIERRA_CORCHETE rank_specifiers
                                | NEW ID ABRE_CORCHETE expression_list CIERRA_CORCHETE rank_specifiers
                                | NEW type ABRE_CORCHETE expression_list CIERRA_CORCHETE array_initializer
                                | NEW ID ABRE_CORCHETE expression_list CIERRA_CORCHETE array_initializer
                                | NEW type ABRE_CORCHETE expression_list CIERRA_CORCHETE
                                | NEW ID ABRE_CORCHETE expression_list CIERRA_CORCHETE
                                | NEW type array_initializer
                                | NEW ID array_initializer'''
    pass


def p_e_delegate_creation_expression(p):
    '''delegate_creation_expression : NEW type_name ABRE_PARENTESIS expression CIERRA_PARENTESIS'''
    pass

def p_e_typeof_expression(p):
    '''typeof_expression : TYPEOF ABRE_PARENTESIS type CIERRA_PARENTESIS
                    | TYPEOF ABRE_PARENTESIS unbound_type_name CIERRA_PARENTESIS
                    | TYPEOF ABRE_PARENTESIS ID CIERRA_PARENTESIS
                    | TYPEOF ABRE_PARENTESIS ID OPERADOR_NAMESPACE ID CIERRA_PARENTESIS
                    | TYPEOF ABRE_PARENTESIS VOID CIERRA_PARENTESIS'''
    pass

def p_e_unbound_type_name(p):
    '''unbound_type_name : ID generic_dimension_specifier
                    | ID OPERADOR_NAMESPACE ID generic_dimension_specifier
                    | unbound_type_name PUNTO ID generic_dimension_specifier
                    | unbound_type_name PUNTO ID '''
    pass

def p_e_generic_dimension_specifier(p):
    '''generic_dimension_specifier : MENOR commas MAYOR
                                    | MENOR MAYOR'''
    pass

def p_e_commas(p):
    '''commas : COMA
            | commas COMA'''
    pass

def p_e_checked_expression(p):
    '''checked_expression : CHECKED ABRE_PARENTESIS expression CIERRA_PARENTESIS'''
    pass

def p_e_unchecked_expression(p):
    '''unchecked_expression : UNCHECKED ABRE_PARENTESIS expression CIERRA_PARENTESIS'''
    pass

def p_e_default_value_expression(p):
    '''default_value_expression : DEFAULT ABRE_PARENTESIS type CIERRA_PARENTESIS'''
    pass

def p_e_anonymous_method_expression(p):
    '''anonymous_method_expression : DELEGATE anonymous_method_signature block
                                    | DELEGATE block'''
    pass

def p_e_anonymous_method_signature(p):
    '''anonymous_method_signature : ABRE_PARENTESIS anonymous_method_parameter_list CIERRA_PARENTESIS
                                    | ABRE_PARENTESIS CIERRA_PARENTESIS'''
    pass

def p_e_anonymous_method_parameter_list(p):
    '''anonymous_method_parameter_list : anonymous_method_parameter
                    | anonymous_method_parameter_list COMA anonymous_method_parameter'''
    pass

def p_e_anonymous_method_parameter(p):
    '''anonymous_method_parameter : parameter_modifier type ID
                                    | type ID'''
    pass

def p_e_unary_expression(p):
    '''unary_expression : primary_expression
                    | SUMA unary_expression
                    | RESTA unary_expression
                    | NOT unary_expression
                    | NOT_BIT unary_expression
                    | pre_increment_expression
                    | pre_decrement_expression
                    | cast_expression
                    | pointer_indirection_expression'''
    pass

def p_e_pre_increment_expression(p):
    '''pre_increment_expression : INCREMENTAL unary_expression
                                | INCREMENTAL BOOLEANO unary_expression'''
    pass

def p_e_pre_decrement_expression(p):
    '''pre_decrement_expression : DECREMENTAL unary_expression
                                | DECREMENTAL BOOLEANO unary_expression'''
    pass

def p_e_cast_expression(p):
    '''cast_expression : ABRE_PARENTESIS type CIERRA_PARENTESIS unary_expression
                        | ABRE_PARENTESIS type CIERRA_PARENTESIS BOOLEANO unary_expression'''
    pass

def p_e_multiplicative_expression(p):
    '''multiplicative_expression : unary_expression
                    | multiplicative_expression MULTIPLICACION unary_expression
                    | multiplicative_expression MULTIPLICACION BOOLEANO unary_expression
                    | multiplicative_expression DIVISION unary_expression
                    | multiplicative_expression DIVISION BOOLEANO unary_expression
                    | multiplicative_expression RESTO unary_expression
                    | multiplicative_expression RESTO BOOLEANO unary_expression'''
    pass

def p_e_additive_expression(p):
    '''additive_expression : multiplicative_expression
                    | additive_expression SUMA multiplicative_expression
                    | additive_expression RESTA multiplicative_expression'''
    pass

def p_e_shift_expression(p):
    '''shift_expression : additive_expression
                    | shift_expression SHIFT_IZQUIERDA additive_expression
                    | shift_expression SHIFT_DERECHA additive_expression'''
    pass

def p_e_relational_expression(p):
    '''relational_expression : shift_expression
                    | relational_expression MENOR shift_expression
                    | relational_expression MAYOR shift_expression
                    | relational_expression SHIFT_IZQUIERDA_ABREVIADO shift_expression
                    | relational_expression SHIFT_DERECHA_ABREVIADO shift_expression
                    | relational_expression IS type
                    | relational_expression AS type'''
    pass

def p_e_equality_expression(p):
    '''equality_expression : relational_expression
                    | equality_expression DOBLE_IGUAL relational_expression
                    | equality_expression DISTINTO relational_expression'''
    pass

def p_e_and_expression(p):
    '''and_expression : equality_expression
                    | and_expression BOOLEANO equality_expression'''
    pass

def p_e_exclusive_or_expression(p):
    '''exclusive_or_expression : and_expression
                    | exclusive_or_expression OR_EXCLUSIVO and_expression'''
    pass

def p_e_inclusive_or_expression(p):
    '''inclusive_or_expression : exclusive_or_expression
                    | inclusive_or_expression OR exclusive_or_expression'''
    pass

def p_e_conditional_and_expression(p):
    '''conditional_and_expression : inclusive_or_expression
                    | conditional_and_expression CONDICIONAL_AND inclusive_or_expression'''
    pass

def p_e_conditional_or_expression(p):
    '''conditional_or_expression : conditional_and_expression
                    | conditional_or_expression CONDICIONAL_OR conditional_and_expression'''
    pass

def p_e_null_coalescing_expression(p):
    '''null_coalescing_expression : conditional_or_expression
                    | conditional_or_expression DOBLE_CONDICIONAL null_coalescing_expression'''
    pass

def p_e_conditional_expression(p):
    '''conditional_expression : null_coalescing_expression
                    | null_coalescing_expression CONDICIONAL expression DOS_PUNTOS expression'''
    pass

def p_e_assignment(p):
    '''assignment : unary_expression assignment_operator expression'''
    pass

def p_e_assignment_operator(p):
    '''assignment_operator : IGUAL
                    | SUMA_ABREVIADA
                    | RESTA_ABREVIADA
                    | MULTIPLICACION_ABREVIADA
                    | DIVISION_ABREVIADA
                    | RESTO_ABREVIADO
                    | BOOLEANO_ABREVIADO
                    | OR_ABREVIADO
                    | OR_EXCLUSIVO_ABREVIADO
                    | SHIFT_DERECHA_ABREVIADO
                    | SHIFT_IZQUIERDA_ABREVIADO'''
    pass

def p_e_expression(p):
    '''expression : conditional_expression
                    | assignment'''
    p[0]=tupla_p(p)

def p_e_constant_expression(p):
    '''constant_expression : expression'''
    pass

def p_e_boolean_expression(p):
    '''boolean_expression : expression'''
    pass

#___A.2.5 Statements______________________________________________________________#

def p_e_statement(p):
    '''statement : labeled_statement
                    | declaration_statement
                    | embedded_statement'''
    pass

def p_e_embedded_statement(p):
    '''embedded_statement : block
                    | empty_statement
                    | expression_statement
                    | selection_statement
                    | iteration_statement
                    | jump_statement
                    | try_statement
                    | checked_statement
                    | unchecked_statement
                    | lock_statement
                    | using_statement
                    | yield_statement
                    | fixed_statement
                    | unsafe_statement'''
    pass

def p_e_block(p):
    '''block : ABRE_LLAVE statement_list CIERRA_LLAVE
                | ABRE_LLAVE CIERRA_LLAVE'''
    pass


def p_e_statement_list(p):
    '''statement_list : statement
                    | statement_list statement'''
    pass

def p_e_empty_statement(p):
    '''empty_statement : PUNTO_COMA'''
    pass

def p_e_labeled_statement(p):
    '''labeled_statement : ID DOS_PUNTOS statement'''
    pass

def p_e_declaration_statement(p):
    '''declaration_statement : local_variable_declaration PUNTO_COMA
                    | local_constant_declaration PUNTO_COMA'''
    pass

def p_e_local_variable_declaration(p):
    '''local_variable_declaration : type local_variable_declarators'''
    pass

def p_e_local_variable_declarators(p):
    '''local_variable_declarators : local_variable_declarator
                    | local_variable_declarators COMA local_variable_declarator'''
    pass

def p_e_local_variable_declarator(p):
    '''local_variable_declarator : ID
                    | ID IGUAL local_variable_initializer'''
    pass

def p_e_local_variable_initializer(p):
    '''local_variable_initializer : expression
                    | array_initializer
                    | stackalloc_initializer'''
    pass

def p_e_local_constant_declaration(p):
    '''local_constant_declaration : CONST type constant_declarators'''
    pass

def p_e_constant_declarators(p):
    '''constant_declarators : constant_declarator
                    | constant_declarators COMA constant_declarator'''
    pass

def p_e_constant_declarator(p):
    '''constant_declarator : ID IGUAL constant_expression'''
    pass

def p_e_expression_statement(p):
    '''expression_statement : statement_expression PUNTO_COMA'''
    pass

def p_e_statement_expression(p):
    '''statement_expression : invocation_expression
                    | object_creation_expression
                    | assignment
                    | post_increment_expression
                    | post_decrement_expression
                    | pre_increment_expression
                    | pre_decrement_expression'''
    pass

def p_e_selection_statement(p):
    '''selection_statement : if_statement
                    | switch_statement'''
    pass

def p_e_if_statement(p):
    '''if_statement : IF ABRE_PARENTESIS boolean_expression CIERRA_PARENTESIS embedded_statement
                    | IF ABRE_PARENTESIS boolean_expression CIERRA_PARENTESIS embedded_statement ELSE embedded_statement'''
    pass

def p_e_switch_statement(p):
    '''switch_statement : SWITCH ABRE_PARENTESIS expression CIERRA_PARENTESIS switch_block'''
    pass

def p_e_switch_block(p):
    '''switch_block : ABRE_LLAVE switch_sections CIERRA_LLAVE
                    | ABRE_LLAVE CIERRA_LLAVE'''
    pass


def p_e_switch_sections(p):
    '''switch_sections : switch_section
                    | switch_sections switch_section'''
    pass

def p_e_switch_section(p):
    '''switch_section : switch_labels statement_list'''
    pass

def p_e_switch_labels(p):
    '''switch_labels : switch_label
                    | switch_labels switch_label'''
    pass

def p_e_switch_label(p):
    '''switch_label : CASE constant_expression DOS_PUNTOS
                    | DEFAULT DOS_PUNTOS'''
    pass

def p_e_iteration_statement(p):
    '''iteration_statement : while_statement
                    | do_statement
                    | for_statement
                    | foreach_statement'''
    pass

def p_e_while_statement(p):
    '''while_statement : WHILE ABRE_PARENTESIS boolean_expression CIERRA_PARENTESIS embedded_statement'''
    pass

def p_e_do_statement(p):
    '''do_statement : DO embedded_statement WHILE ABRE_PARENTESIS boolean_expression CIERRA_PARENTESIS PUNTO_COMA'''
    pass

def p_e_for_statement(p):
    '''for_statement : FOR ABRE_PARENTESIS opcional_for_initializer PUNTO_COMA opcional_for_condition PUNTO_COMA opcional_for_iterator CIERRA_PARENTESIS embedded_statement'''
    pass

def p_e_opcional_for_initializer(p):
    '''opcional_for_initializer : for_initializer
                                | '''
    pass

def p_e_opcional_for_condition(p):
    '''opcional_for_condition : for_condition
                                | '''
    pass

def p_e_opcional_for_iterator(p):
    '''opcional_for_iterator : for_iterator
                                | '''
    pass

def p_e_for_initializer(p):
    '''for_initializer : local_variable_declaration
                    | statement_expression_list'''
    pass

def p_e_for_condition(p):
    '''for_condition : boolean_expression'''
    pass

def p_e_for_iterator(p):
    '''for_iterator : statement_expression_list'''
    pass

def p_e_statement_expression_list(p):
    '''statement_expression_list : statement_expression
                    | statement_expression_list COMA statement_expression'''
    pass

def p_e_foreach_statement(p):
    '''foreach_statement : FOREACH ABRE_PARENTESIS type ID IN expression CIERRA_PARENTESIS embedded_statement'''
    pass

def p_e_jump_statement(p):
    '''jump_statement : break_statement
                    | continue_statement
                    | goto_statement
                    | return_statement
                    | throw_statement'''
    pass

def p_e_break_statement(p):
    '''break_statement : BREAK PUNTO_COMA'''
    pass

def p_e_continue_statement(p):
    '''continue_statement : CONTINUE PUNTO_COMA'''
    pass

def p_e_goto_statement(p):
    '''goto_statement : GOTO ID PUNTO_COMA
                    | GOTO CASE constant_expression PUNTO_COMA
                    | GOTO DEFAULT PUNTO_COMA'''
    pass

def p_e_return_statement(p):
    '''return_statement : RETURN expression PUNTO_COMA
                        | RETURN PUNTO_COMA'''
    pass


def p_e_throw_statement(p):
    '''throw_statement : THROW expression PUNTO_COMA
                        | THROW PUNTO_COMA'''
    pass


def p_e_try_statement(p):
    '''try_statement : TRY block catch_clauses
                    | TRY block catch_clauses finally_clause
                    | TRY block finally_clause'''
    pass


def p_e_catch_clauses(p):
    '''catch_clauses : specific_catch_clauses
                    | specific_catch_clauses general_catch_clause
                    | general_catch_clause'''
    pass

def p_e_specific_catch_clauses(p):
    '''specific_catch_clauses : specific_catch_clause
                    | specific_catch_clauses specific_catch_clause'''
    pass

def p_e_specific_catch_clause(p):
    '''specific_catch_clause : CATCH ABRE_PARENTESIS type_name ID CIERRA_PARENTESIS block
                            | CATCH ABRE_PARENTESIS OBJECT ID CIERRA_PARENTESIS block
                            | CATCH ABRE_PARENTESIS STRING ID CIERRA_PARENTESIS block
                            | CATCH ABRE_PARENTESIS type_name CIERRA_PARENTESIS block
                            | CATCH ABRE_PARENTESIS OBJECT CIERRA_PARENTESIS block
                            | CATCH ABRE_PARENTESIS STRING CIERRA_PARENTESIS block'''
    pass


def p_e_general_catch_clause(p):
    '''general_catch_clause : CATCH block'''
    pass

def p_e_finally_clause(p):
    '''finally_clause : FINALLY block'''
    pass

def p_e_checked_statement(p):
    '''checked_statement : CHECKED block'''
    pass

def p_e_unchecked_statement(p):
    '''unchecked_statement : UNCHECKED block'''
    pass

def p_e_lock_statement(p):
    '''lock_statement : LOCK ABRE_PARENTESIS expression CIERRA_PARENTESIS embedded_statement'''
    pass

def p_e_using_statement(p):
    '''using_statement : USING ABRE_PARENTESIS resource_acquisition CIERRA_PARENTESIS embedded_statement'''
    pass

def p_e_resource_acquisition(p):
    '''resource_acquisition : local_variable_declaration
                    | expression'''
    pass

def p_e_yield_statement(p):
    '''yield_statement : YIELD RETURN expression PUNTO_COMA
                    | YIELD BREAK PUNTO_COMA'''
    pass

def p_e_namespace_declaration(p):
    '''namespace_declaration : NAMESPACE qualified_identifier namespace_body PUNTO_COMA
                                | NAMESPACE qualified_identifier namespace_body'''
    pass


def p_e_qualified_identifier(p):
    '''qualified_identifier : ID
                    | qualified_identifier PUNTO ID'''
    pass

def p_e_namespace_body(p):
    '''namespace_body : ABRE_LLAVE opcional_extern_alias_directives opcional_using_directives opcional_namespace_member_declarations CIERRA_LLAVE'''
    pass


def p_e_extern_alias_directives(p):
    '''extern_alias_directives : extern_alias_directive
                    | extern_alias_directives extern_alias_directive'''
    pass

def p_e_extern_alias_directive(p):
    '''extern_alias_directive : EXTERN ALIAS ID PUNTO_COMA'''
    pass

def p_e_using_directives(p):
    '''using_directives : using_directive
                    | using_directives using_directive'''
    pass

def p_e_using_directive(p):
    '''using_directive : using_alias_directive
                    | using_namespace_directive'''
    pass

def p_e_using_alias_directive(p):
    '''using_alias_directive : USING ID IGUAL type_name PUNTO_COMA'''
    pass

def p_e_using_namespace_directive(p):
    '''using_namespace_directive : USING type_name PUNTO_COMA'''
    pass

def p_e_namespace_member_declarations(p):
    '''namespace_member_declarations : namespace_member_declaration
                    | namespace_member_declarations namespace_member_declaration'''
    pass

def p_e_namespace_member_declaration(p):
    '''namespace_member_declaration : namespace_declaration
                    | type_declaration'''
    pass

def p_e_type_declaration(p):
    '''type_declaration : class_declaration
                    | struct_declaration
                    | interface_declaration
                    | enum_declaration
                    | delegate_declaration'''
    pass

def p_e_qualified_alias_member(p):
    '''qualified_alias_member : ID OPERADOR_NAMESPACE ID type_argument_list
                                | ID OPERADOR_NAMESPACE ID'''
    pass



#___A.2.6 Clases______________________________________________________________#

def p_e_class_declaration(p):
    '''class_declaration : opcional_attributes opcional_modifiers opcional_partial CLASS ID opcional_type_parameter_list opcional_class_base opcional_type_parameter_constraints_clauses class_body PUNTO_COMA
                        | opcional_attributes opcional_modifiers opcional_partial CLASS ID opcional_type_parameter_list opcional_class_base opcional_type_parameter_constraints_clauses class_body'''

    if p[4]=='class':
        Parser_csh.c.propiedades['name']=p[5]

        if p[7]!='':
            Parser_csh.c.padre=p[6]

        aux=p[9].strip('{')
        aux=aux.strip('}')
        aux=aux.strip(' ')

        cuerpo_clase=aux.split(';')

        if '' in cuerpo_clase:
            cuerpo_clase.pop()

        for regla in cuerpo_clase:
            regla=regla.strip(' ').split(' ')

            if regla[2] == '[':

                Parser_csh.a.propiedades['name']=regla[4]
                Parser_csh.a.tipo=regla[1]

                Parser_csh.nuevo_atributo()

            else:
                if len(regla)>3:
                    Parser_csh.m.propiedades['name']=regla[2]

                    Parser_csh.p.propiedades['name']='return'
                    Parser_csh.p.tipo=regla[1]

                    Parser_csh.nuevo_parametro()

                    if len(p)==5:
                        Parser_csh.p.propiedades['name']=regla[5]
                        Parser_csh.p.tipo=regla[4]

                        Parser_csh.nuevo_parametro()

                    Parser_csh.nuevo_metodo()

                else:
                    Parser_csh.a.propiedades['name']=regla[2]
                    Parser_csh.a.tipo=regla[1]

                    Parser_csh.nuevo_atributo()

        Parser_csh.nueva_clase()

def p_e_opcional_attributes(p):
    '''opcional_attributes : attributes
                            | '''
    pass

def p_e_opcional_partial(p):
    '''opcional_partial : PARTIAL
                        | '''
    pass

def p_e_opcional_type_parameter_list(p):
    '''opcional_type_parameter_list : type_parameter_list
                                    | '''
    pass

def p_e_opcional_class_base(p):
    '''opcional_class_base : class_base
                            | '''
    p[0]=tupla_p(p)

def p_e_opcional_type_parameter_constraints_clauses(p):
    '''opcional_type_parameter_constraints_clauses : type_parameter_constraints_clauses
                                                    | '''
    pass

def p_e_class_base(p):
    '''class_base : DOS_PUNTOS OBJECT
            | DOS_PUNTOS STRING
            | DOS_PUNTOS interface_type_list
            | DOS_PUNTOS type_name COMA interface_type_list
            | DOS_PUNTOS OBJECT COMA interface_type_list
            | DOS_PUNTOS STRING COMA interface_type_list'''
    p[0]=p[2]

def p_e_interface_type_list(p):
    '''interface_type_list : type_name
            | interface_type_list COMA type_name'''
    p[0]=tupla_p(p)

def p_e_class_body(p):
    '''class_body : ABRE_LLAVE class_member_declarations CIERRA_LLAVE
                    | ABRE_LLAVE CIERRA_LLAVE'''
    p[0]=tupla_p(p)

def p_e_class_member_declarations(p):
    '''class_member_declarations : class_member_declaration
                    | class_member_declarations class_member_declaration'''
    p[0]=tupla_p(p)

def p_e_class_member_declaration(p):
    '''class_member_declaration : constant_declaration
                    | field_declaration
                    | method_declaration
                    | property_declaration
                    | event_declaration
                    | indexer_declaration
                    | operator_declaration
                    | constructor_declaration
                    | finalizer_declaration
                    | static_constructor_declaration
                    | type_declaration'''
    p[0]=tupla_p(p)

def p_e_constant_declaration(p):
    '''constant_declaration : opcional_attributes opcional_modifiers CONST type constant_declarators PUNTO_COMA'''
    pass

def p_e_field_declaration(p):
    '''field_declaration : opcional_attributes opcional_modifiers type variable_declarators PUNTO_COMA'''
    p[0]=tupla_p(p)

def p_e_variable_declarators(p):
    '''variable_declarators : variable_declarator
                    | variable_declarators COMA variable_declarator'''
    p[0]=tupla_p(p)

def p_e_variable_declarator(p):
    '''variable_declarator : ID
                | ID IGUAL variable_initializer'''
    p[0]=tupla_p(p)

def p_e_variable_initializer(p):
    '''variable_initializer : expression
                | array_initializer'''
    pass

def p_e_method_declaration(p):
    '''method_declaration : method_header method_body'''
    p[0]=tupla_p(p)

def p_e_method_header(p):
    '''method_header : opcional_attributes opcional_modifiers type simple_name opcional_type_parameter_list ABRE_PARENTESIS opcional_formal_parameter_list CIERRA_PARENTESIS opcional_type_parameter_constraints_clauses'''
    p[0]=tupla_p(p)

def p_e_opcional_formal_parameter_list(p):
    '''opcional_formal_parameter_list : formal_parameter_list
                                        | '''
    p[0]=tupla_p(p)

def p_e_method_body(p):
    '''method_body : block
            | PUNTO_COMA'''
    pass

def p_e_formal_parameter_list(p):
    '''formal_parameter_list : fixed_parameters
                    | fixed_parameters COMA parameter_array
                    | parameter_array'''
    p[0]=tupla_p(p)

def p_e_fixed_parameters(p):
    '''fixed_parameters : fixed_parameter
                | fixed_parameters COMA fixed_parameter'''
    p[0]=tupla_p(p)

def p_e_fixed_parameter(p):
    '''fixed_parameter : opcional_attributes opcional_parameter_modifier type ID'''
    p[0]=tupla_p(p)

def p_e_opcional_parameter_modifier(p):
    '''opcional_parameter_modifier : parameter_modifier
                                    | '''
    pass

def p_e_parameter_modifier(p):
    '''parameter_modifier : REF
                | OUT'''
    pass

def p_e_parameter_array(p):
    '''parameter_array : opcional_attributes PARAMS array_type ID'''
    pass

def p_e_property_declaration(p):
    '''property_declaration : opcional_attributes opcional_modifiers type simple_name ABRE_LLAVE accessor_declarations CIERRA_LLAVE'''
    pass

def p_e_accessor_declarations(p):
    '''accessor_declarations : get_accessor_declaration set_accessor_declaration
                            | get_accessor_declaration
                            | set_accessor_declaration get_accessor_declaration
                            | set_accessor_declaration'''
    pass

def p_e_get_accessor_declaration(p):
    '''get_accessor_declaration : opcional_attributes opcional_modifiers GET accessor_body'''
    pass

def p_e_set_accessor_declaration(p):
    '''set_accessor_declaration : opcional_attributes opcional_modifiers SET accessor_body'''
    pass

def p_e_accessor_body(p):
    '''accessor_body : block
            | PUNTO_COMA'''
    pass

def p_e_event_declaration(p):
    '''event_declaration : opcional_attributes opcional_modifiers EVENT type variable_declarators PUNTO_COMA
            | opcional_attributes opcional_modifiers EVENT type simple_name
            | ABRE_LLAVE event_accessor_declarations CIERRA_LLAVE'''
    pass

def p_e_event_accessor_declarations(p):
    '''event_accessor_declarations : add_accessor_declaration remove_accessor_declaration
                    | remove_accessor_declaration add_accessor_declaration'''
    pass

def p_e_add_accessor_declaration(p):
    '''add_accessor_declaration : opcional_attributes ADD block'''
    pass

def p_e_remove_accessor_declaration(p):
    '''remove_accessor_declaration : opcional_attributes REMOVE block'''
    pass


def p_e_indexer_declaration(p):
    '''indexer_declaration : opcional_attributes opcional_modifiers indexer_declarator ABRE_LLAVE accessor_declarations CIERRA_LLAVE'''
    pass

def p_e_indexer_declarator(p):
    '''indexer_declarator : type THIS ABRE_CORCHETE formal_parameter_list CIERRA_CORCHETE
                | type type_name PUNTO THIS ABRE_CORCHETE formal_parameter_list CIERRA_CORCHETE'''
    pass

def p_e_operator_declaration(p):
    '''operator_declaration : opcional_attributes opcional_modifiers operator_declarator operator_body'''
    pass

def p_e_operator_declarator(p):
    '''operator_declarator : unary_operator_declarator
                | binary_operator_declarator
                | conversion_operator_declarator '''
    pass

def p_e_unary_operator_declarator(p):
    '''unary_operator_declarator : type OPERATOR overloadable_unary_operator ABRE_PARENTESIS type ID CIERRA_PARENTESIS'''
    pass

def p_e_overloadable_unary_operator(p):
    '''overloadable_unary_operator : SUMA RESTA NOT NOT_BIT INCREMENTAL DECREMENTAL TRUE FALSE'''
    pass


def p_e_binary_operator_declarator(p):
    '''binary_operator_declarator : type OPERATOR overloadable_binary_operator ABRE_PARENTESIS type ID COMA type ID CIERRA_PARENTESIS'''
    pass

def p_e_overloadable_binary_operator(p):
    '''overloadable_binary_operator : SUMA RESTA MULTIPLICACION DIVISION RESTO
                        | BOOLEANO OR OR_EXCLUSIVO
                        | SHIFT_IZQUIERDA SHIFT_DERECHA
                        | DOBLE_IGUAL DISTINTO MAYOR MENOR MAYOR_IGUAL MENOR_IGUAL'''
    pass

def p_e_conversion_operator_declarator(p):
    '''conversion_operator_declarator : IMPLICIT OPERATOR type ABRE_PARENTESIS type ID CIERRA_PARENTESIS
                        | EXPLICIT OPERATOR type ABRE_PARENTESIS type ID CIERRA_PARENTESIS'''
    pass

def p_e_operator_body(p):
    '''operator_body : block
                | PUNTO_COMA'''
    pass

def p_e_constructor_declaration(p):
    '''constructor_declaration : opcional_attributes opcional_modifiers constructor_declarator constructor_body'''
    pass

def p_e_constructor_declarator(p):
    '''constructor_declarator : ID ABRE_PARENTESIS opcional_formal_parameter_list CIERRA_PARENTESIS opcional_constructor_initializer'''
    pass


def p_e_opcional_constructor_initializer(p):
    '''opcional_constructor_initializer : constructor_initializer
            | '''
    pass


def p_e_constructor_initializer(p):
    '''constructor_initializer : DOS_PUNTOS BASE ABRE_PARENTESIS opcional_argument_list CIERRA_PARENTESIS
                    | DOS_PUNTOS THIS ABRE_PARENTESIS opcional_argument_list CIERRA_PARENTESIS'''
    pass

def p_e_opcional_argument_list(p):
    '''opcional_argument_list : argument_list
            | '''
    pass

def p_e_constructor_body(p):
    '''constructor_body : block
                | PUNTO_COMA'''
    pass

def p_e_static_constructor_declaration(p):
    '''static_constructor_declaration : opcional_attributes static_constructor_modifiers ID ABRE_PARENTESIS CIERRA_PARENTESIS static_constructor_body
                                    | opcional_attributes STATIC ID ABRE_PARENTESIS CIERRA_PARENTESIS static_constructor_body'''
    pass


def p_e_static_constructor_modifiers(p):
    '''static_constructor_modifiers : EXTERN STATIC
                    | STATIC EXTERN'''
    pass




def p_e_static_constructor_body(p):
    '''static_constructor_body : block
                    | PUNTO_COMA'''
    pass

def p_e_finalizer_declaration(p):
    '''finalizer_declaration : opcional_attributes EXTERN NOT_BIT ID ABRE_PARENTESIS CIERRA_PARENTESIS finalizer_body
                            | opcional_attributes NOT_BIT ID ABRE_PARENTESIS CIERRA_PARENTESIS finalizer_body'''
    pass



def p_e_finalizer_body(p):
    '''finalizer_body : block
                | PUNTO_COMA
                '''
    pass

#___A.2.7 Structs______________________________________________________________#

def p_e_struct_declaration(p):
    '''struct_declaration : opcional_attributes opcional_modifiers opcional_partial STRUCT ID opcional_type_parameter_list opcional_struct_interfaces opcional_type_parameter_constraints_clauses struct_body PUNTO_COMA
                        | opcional_attributes opcional_modifiers opcional_partial STRUCT ID opcional_type_parameter_list opcional_struct_interfaces opcional_type_parameter_constraints_clauses struct_body'''
    pass

def p_e_opcional_struct_interfaces(p):
    '''opcional_struct_interfaces : struct_interfaces
                                    | '''
    pass

def p_e_struct_interfaces(p):
    '''struct_interfaces : DOS_PUNTOS interface_type_list'''
    pass

def p_e_struct_body(p):
    '''struct_body : ABRE_LLAVE struct_member_declarations CIERRA_LLAVE
                    | ABRE_LLAVE CIERRA_LLAVE'''
    pass

def p_e_struct_member_declarations(p):
    '''struct_member_declarations : struct_member_declaration
                                    | struct_member_declarations struct_member_declaration'''
    pass

def p_e_struct_member_declaration(p):
    '''struct_member_declaration : constant_declaration
                                    | field_declaration
                                    | method_declaration
                                    | property_declaration
                                    | event_declaration
                                    | indexer_declaration
                                    | operator_declaration
                                    | constructor_declaration
                                    | static_constructor_declaration
                                    | type_declaration'''
    pass

#___A.2.8 Arrays______________________________________________________________#

def p_e_array_initializer(p):
    '''array_initializer : ABRE_LLAVE variable_initializer_list CIERRA_LLAVE
                            | ABRE_LLAVE variable_initializer_list COMA CIERRA_LLAVE
                            | ABRE_LLAVE CIERRA_LLAVE'''
    pass

def p_e_variable_initializer_list(p):
    '''variable_initializer_list : variable_initializer
                                    | variable_initializer_list COMA variable_initializer'''
    pass

#___A.2.9 Interfaces______________________________________________________________#

def p_e_interface_declaration(p):
    '''interface_declaration : opcional_attributes opcional_modifiers opcional_partial INTERFACE ID opcional_type_parameter_list opcional_interface_base opcional_type_parameter_constraints_clauses interface_body PUNTO_COMA
                                | opcional_attributes opcional_modifiers opcional_partial INTERFACE ID opcional_type_parameter_list opcional_interface_base opcional_type_parameter_constraints_clauses interface_body'''
    pass

def p_e_opcional_interface_base(p):
    '''opcional_interface_base : interface_base
                                | '''
    pass

def p_e_interface_base(p):
    '''interface_base : DOS_PUNTOS interface_type_list'''
    pass

def p_e_interface_body(p):
    '''interface_body : ABRE_LLAVE interface_member_declarations CIERRA_LLAVE
                        | ABRE_LLAVE CIERRA_LLAVE'''
    pass

def p_e_interface_member_declarations(p):
    '''interface_member_declarations : interface_member_declaration
                                        | interface_member_declarations interface_member_declaration'''
    pass

def p_e_interface_member_declaration(p):
    '''interface_member_declaration : interface_method_declaration
                                        | interface_property_declaration
                                        | interface_event_declaration
                                        | interface_indexer_declaration'''
    pass

def p_e_interface_method_declaration(p):
    '''interface_method_declaration : opcional_attributes opcional_new type ID opcional_type_parameter_list ABRE_PARENTESIS opcional_formal_parameter_list CIERRA_PARENTESIS opcional_type_parameter_constraints_clauses PUNTO_COMA'''
    pass

def p_e_opcional_new(p):
    '''opcional_new : NEW
                    | '''
    pass



def p_e_interface_property_declaration(p):
    '''interface_property_declaration : attributes NEW type ID ABRE_LLAVE interface_accessors CIERRA_LLAVE
                                        | attributes type ID ABRE_LLAVE interface_accessors CIERRA_LLAVE
                                        | NEW type ID ABRE_LLAVE interface_accessors CIERRA_LLAVE
                                        | type ID ABRE_LLAVE interface_accessors CIERRA_LLAVE'''
    pass

def p_e_interface_accessors(p):
    '''interface_accessors : attributes GET PUNTO_COMA
                            | GET PUNTO_COMA
                            | attributes SET PUNTO_COMA
                            | SET PUNTO_COMA
                            | attributes GET PUNTO_COMA attributes SET PUNTO_COMA
                            | GET PUNTO_COMA attributes SET PUNTO_COMA
                            | attributes GET PUNTO_COMA SET PUNTO_COMA
                            | GET PUNTO_COMA SET PUNTO_COMA
                            | attributes SET PUNTO_COMA attributes GET PUNTO_COMA
                            | SET PUNTO_COMA attributes GET PUNTO_COMA
                            | attributes SET PUNTO_COMA GET PUNTO_COMA
                            | SET PUNTO_COMA GET PUNTO_COMA'''
    pass

def p_e_interface_event_declaration(p):
    '''interface_event_declaration : attributes NEW EVENT type ID PUNTO_COMA
                                    | NEW EVENT type ID PUNTO_COMA
                                    | attributes EVENT type ID PUNTO_COMA
                                    | EVENT type ID PUNTO_COMA'''
    pass

def p_e_interface_indexer_declaration(p):
    '''interface_indexer_declaration : attributes NEW type THIS ABRE_CORCHETE formal_parameter_list CIERRA_CORCHETE ABRE_LLAVE interface_accessors CIERRA_LLAVE
                                        | attributes type THIS ABRE_CORCHETE formal_parameter_list CIERRA_CORCHETE ABRE_LLAVE interface_accessors CIERRA_LLAVE
                                        | NEW type THIS ABRE_CORCHETE formal_parameter_list CIERRA_CORCHETE ABRE_LLAVE interface_accessors CIERRA_LLAVE
                                        | type THIS ABRE_CORCHETE formal_parameter_list CIERRA_CORCHETE ABRE_LLAVE interface_accessors CIERRA_LLAVE'''

    pass

#___A.2.10 Enums______________________________________________________________#

def p_e_enum_declaration(p):
    '''enum_declaration : opcional_attributes opcional_modifiers ENUM ID opcional_enum_base enum_body PUNTO_COMA
                        | opcional_attributes opcional_modifiers ENUM ID opcional_enum_base enum_body'''

    for elemento in lista_enum:

        Parser_csh.a.propiedades['name']=elemento
        Parser_csh.a.tipo=''

        Parser_csh.nuevo_atributo()

    Parser_csh.c.propiedades['name']=p[4]

    Parser_csh.nueva_clase()

def p_e_opcional_enum_base(p):
    '''opcional_enum_base : enum_base
                    | '''
    pass

def p_e_enum_base(p):
    '''enum_base : DOS_PUNTOS integral_type'''
    pass

def p_e_enum_body(p):
    '''enum_body : ABRE_LLAVE enum_member_declarations CIERRA_LLAVE
                    | ABRE_LLAVE CIERRA_LLAVE
                    | ABRE_LLAVE enum_member_declarations COMA CIERRA_LLAVE'''
    pass

def p_e_enum_member_declarations(p):
    '''enum_member_declarations : enum_member_declaration
                                | enum_member_declarations COMA enum_member_declaration'''
    pass

def p_e_enum_member_declaration(p):
    '''enum_member_declaration : attributes ID
                                | ID
                                | attributes ID IGUAL constant_expression
                                | ID IGUAL constant_expression'''

    lista_enum.append(p[1])

#___A.2.11 Delegates______________________________________________________________#

def p_e_delegate_declaration(p):
    '''delegate_declaration : opcional_attributes opcional_modifiers DELEGATE type ID opcional_type_parameter_list ABRE_PARENTESIS opcional_formal_parameter_list CIERRA_PARENTESIS opcional_type_parameter_constraints_clauses PUNTO_COMA'''
    pass

#___A.2.12 Attributes______________________________________________________________#

def p_e_global_attributes(p):
    '''global_attributes : global_attribute_sections'''
    pass

def p_e_global_attribute_sections(p):
    '''global_attribute_sections : global_attribute_section
                                | global_attribute_sections global_attribute_section'''
    pass

def p_e_global_attribute_section(p):
    '''global_attribute_section : ABRE_CORCHETE global_attribute_target_specifier attribute_list CIERRA_CORCHETE
                                | ABRE_CORCHETE global_attribute_target_specifier attribute_list COMA CIERRA_CORCHETE'''
    pass


def p_e_global_attribute_target_specifier(p):
    '''global_attribute_target_specifier : global_attribute_target DOS_PUNTOS'''
    pass


def p_e_global_attribute_target(p):
    '''global_attribute_target : ID
                                | keyword'''

    pass

def p_e_attributes(p):
    '''attributes : attribute_sections'''
    pass

def p_e_attribute_sections(p):
    '''attribute_sections : attribute_section
                            | attribute_sections attribute_section'''
    pass

def p_e_attribute_section(p):
    '''attribute_section : ABRE_CORCHETE attribute_target_specifier attribute_list CIERRA_CORCHETE
                        | ABRE_CORCHETE attribute_list CIERRA_CORCHETE
                        | ABRE_CORCHETE attribute_target_specifier attribute_list COMA CIERRA_CORCHETE
                        | ABRE_CORCHETE attribute_list COMA CIERRA_CORCHETE'''
    pass

def p_e_attribute_target_specifier(p):
    '''attribute_target_specifier : attribute_target DOS_PUNTOS'''
    pass

def p_e_attribute_target(p):
    '''attribute_target : ID
                        | keyword'''
    pass

def p_e_attribute_list(p):
    '''attribute_list : attribute
                        | attribute_list COMA attribute'''
    pass

def p_e_attribute(p):
    '''attribute : attribute_name attribute_arguments
                    | attribute_name'''
    pass

def p_e_attribute_name(p):
    '''attribute_name : type_name'''
    pass

def p_e_attribute_arguments(p):
    '''attribute_arguments : ABRE_PARENTESIS positional_argument_list CIERRA_PARENTESIS
                            | ABRE_PARENTESIS CIERRA_PARENTESIS
                            | ABRE_PARENTESIS positional_argument_list COMA named_argument_list CIERRA_PARENTESIS
                            | ABRE_PARENTESIS named_argument_list CIERRA_PARENTESIS'''
    pass

def p_e_positional_argument_list(p):
    '''positional_argument_list : positional_argument
                                | positional_argument_list COMA positional_argument'''
    pass

def p_e_positional_argument(p):
    '''positional_argument : attribute_argument_expression'''
    pass

def p_e_named_argument_list(p):
    '''named_argument_list : named_argument
                            | named_argument_list COMA named_argument'''
    pass

def p_e_named_argument(p):
    '''named_argument : ID IGUAL attribute_argument_expression'''
    pass

def p_e_attribute_argument_expression(p):
    '''attribute_argument_expression : expression'''
    pass

#___A.2.13 Generics______________________________________________________________#

def p_e_type_parameter_list(p):
    '''type_parameter_list : MENOR type_parameters MAYOR'''
    pass

def p_e_type_parameters(p):
    '''type_parameters : attributes ID
                        | ID
                        | type_parameters COMA attributes ID
                        | type_parameters COMA ID'''
    pass

def p_e_type_argument_list(p):
    '''type_argument_list : MENOR type_arguments MAYOR'''
    pass

def p_e_type_arguments(p):
    '''type_arguments : type_argument
                        | type_arguments COMA type_argument'''
    pass

def p_e_type_argument(p):
    '''type_argument : type'''
    pass

def p_e_type_parameter_constraints_clauses(p):
    '''type_parameter_constraints_clauses : type_parameter_constraints_clause
                                            | type_parameter_constraints_clauses type_parameter_constraints_clause'''
    pass

def p_e_type_parameter_constraints_clause(p):
    '''type_parameter_constraints_clause : WHERE ID DOS_PUNTOS type_parameter_constraints'''
    pass

def p_e_type_parameter_constraints(p):
    '''type_parameter_constraints : primary_constraint
                                    | secondary_constraints
                                    | constructor_constraint
                                    | primary_constraint COMA secondary_constraints
                                    | OBJECT COMA ID
                                    | STRING COMA ID
                                    | CLASS COMA ID
                                    | STRUCT COMA ID
                                    | type_name COMA secondary_constraints
                                    | primary_constraint COMA constructor_constraint
                                    | type_name COMA constructor_constraint
                                    | secondary_constraints COMA constructor_constraint
                                    | ID COMA constructor_constraint
                                    | primary_constraint COMA secondary_constraints COMA constructor_constraint
                                    | primary_constraint COMA ID COMA constructor_constraint
                                    | type_name COMA secondary_constraints COMA constructor_constraint
                                    | type_name COMA ID COMA constructor_constraint'''
    pass

# type_parameter_constraints deberia contener la regla ID. Ver si esto trae problemas

def p_e_primary_constraint(p):
    '''primary_constraint : OBJECT
                            | STRING
                            | CLASS
                            | STRUCT'''
    pass

def p_e_secondary_constraints(p):
    '''secondary_constraints : type_name
                                | secondary_constraints COMA type_name'''
    pass

# En secondary_constraints falta la regla secondary_constraints COMA ID. De agregarla se da un conflicto de r/r con simple_name : ID. Ver si hace falta.

def p_e_constructor_constraint(p):
    '''constructor_constraint : NEW ABRE_PARENTESIS CIERRA_PARENTESIS'''
    pass

#A.3 Grammar extensions for UNSAFE code

def p_e_unsafe_statement(p):
    ''' unsafe_statement : UNSAFE block '''

def p_e_pointer_type(p):
    '''pointer_type : unmanaged_type MULTIPLICACION
                    | VOID MULTIPLICACION '''
    pass

def p_e_unmanaged_type(p):
    '''unmanaged_type : type'''
    pass

def p_e_pointer_indirection_expression(p):
    '''pointer_indirection_expression : MULTIPLICACION unary_expression
                                        | MULTIPLICACION BOOLEANO unary_expression'''
    pass

def p_e_pointer_member_access(p):
    '''pointer_member_access :  primary_expression FLECHA ID type_argument_list
                            | primary_expression FLECHA ID'''
    pass

def p_e_pointer_element_access(p):
    '''pointer_element_access : primary_no_array_creation_expression ABRE_CORCHETE expression CIERRA_CORCHETE
                            | ID type_argument_list ABRE_CORCHETE expression CIERRA_CORCHETE
                            | ID ABRE_CORCHETE expression CIERRA_CORCHETE'''
    pass

def p_e_sizeof_expression(p):
    '''sizeof_expression :  SIZEOF ABRE_PARENTESIS unmanaged_type CIERRA_PARENTESIS'''
    pass

def p_e_fixed_statement(p):
    '''fixed_statement : FIXED ABRE_PARENTESIS pointer_type fixed_pointer_declarators CIERRA_PARENTESIS embedded_statement'''
    pass

def p_e_fixed_pointer_declarators(p):
    '''fixed_pointer_declarators :  fixed_pointer_declarator
                                    | fixed_pointer_declarators COMA fixed_pointer_declarator'''
    pass

def p_e_fixed_pointer_declarator(p):
    '''fixed_pointer_declarator : ID IGUAL fixed_pointer_initializer'''
    pass


def p_e_fixed_pointer_initializer(p):
    '''fixed_pointer_initializer :  BOOLEANO variable_reference
                                    | expression'''
    pass

def p_e_stackalloc_initializer(p):
    '''stackalloc_initializer : STACKALLOC unmanaged_type ABRE_CORCHETE expression CIERRA_CORCHETE'''
    pass

def p_e_opcional_modifiers(p):
    '''opcional_modifiers : NEW
                            | PUBLIC
                            | PROTECTED
                            | INTERNAL
                            | PRIVATE
                            | ABSTRACT
                            | SEALED
                            | STATIC
                            | UNSAFE
                            | READONLY
                            | VOLATILE
                            | VIRTUAL
                            | OVERRIDE
                            | EXTERN
                            | PROTECTED INTERNAL
                            | INTERNAL PROTECTED
                            | '''
    p[0]=tupla_p(p)

#___Keywords______________________________________________________________#

def p_e_keyword(p):
    '''keyword : ABSTRACT
                | AS
                | BASE
                | BOOL
                | BREAK
                | BYTE
                | CASE
                | CATCH
                | CHAR
                | CHECKED
                | CLASS
                | CONST
                | CONTINUE
                | DECIMAL
                | DEFAULT
                | DELEGATE
                | DO
                | DOUBLE
                | ELSE
                | ENUM
                | EVENT
                | EXPLICIT
                | EXTERN
                | FALSE
                | FINALLY
                | FIXED
                | FLOAT
                | FOR
                | FOREACH
                | GOTO
                | IF
                | IMPLICIT
                | IN
                | INT
                | INTERFACE
                | INTERNAL
                | IS
                | LOCK
                | LONG
                | NAMESPACE
                | NEW
                | NULL
                | OBJECT
                | OPERATOR
                | OUT
                | OVERRIDE
                | PARAMS
                | PRIVATE
                | PROTECTED
                | PUBLIC
                | READONLY
                | REF
                | RETURN
                | SBYTE
                | SEALED
                | SHORT
                | SIZEOF
                | STACKALLOC
                | STATIC
                | STRING
                | STRUCT
                | SWITCH
                | THIS
                | THROW
                | TRUE
                | TRY
                | TYPEOF
                | UINT
                | ULONG
                | UNCHECKED
                | UNSAFE
                | USHORT
                | USING
                | VIRTUAL
                | VOID
                | VOLATILE
                | WHILE
                | PARTIAL
                | YIELD
                | ALIAS
                | WHERE
                | GET
                | SET
                | block
                | ADD
                | REMOVE'''
    pass

#___Literals______________________________________________________________#

def p_e_literal(p):
    '''literal : boolean_literal
                | integer_literal
                | real_literal
                | CARACTER
                | CADENA_CARACTERES
                | NULL'''
    pass

def p_e_boolean_literal(p):
    '''boolean_literal : TRUE
                | FALSE'''
    pass

def p_e_integer_literal(p):
    '''integer_literal : SUMA DIGITO
                        | RESTA DIGITO'''
    pass

def p_e_real_literal(p):
    '''real_literal : SUMA DIGITO PUNTO DIGITO EXPONENCIAL
                    | RESTA DIGITO PUNTO DIGITO EXPONENCIAL
                    | SUMA DIGITO EXPONENCIAL
                    | RESTA DIGITO EXPONENCIAL'''
    pass

#Control de Errores
def p_error(t):
    print "Error sintactico en linea %d, token='%s'" % (t.lineno, t.value)

if __name__ == '__main__':
    #Se crea un analizador sintactico
    p=yacc.yacc()                      
    print p.parse(
'''
using System ;
using System . Collections . Generic ;
using System . Linq ;
using System . Text ;

namespace Pruebas_Unitarias
{
    class ComponenteSalario
    {
        public TipoComponente concepto ;
        public int monto ;

    }
    class Empleado
    {
        public string nombre ;
        public float salario ;
        public int edad ;
        public DateTime fechaNacimiento ;
        public Gerente gerente ;
        public TrabajaRol [ ] trabajarols ;
        public Departamento [ ] departamentos ;
        public ComponenteSalario [ ] componenetesalarios ;
        public void esCumple ( ) { }
    }
    class TrabajaRol
    {
        public DateTime FechaInicio ;
        public string Rol ;
        public Departamento [ ] departamentos ;
        public Empleado [ ] empleados ;
    }
    class Gerente : Empleado
    {
        public Departamento [ ] departamentos ;
        public Empleado [ ] empleados ;
    }

    enum TipoComponente
    {
        basico , bonificable
    }
    class Departamento
    {
        public string nombre ;
        public int NumeroEmpleado ;
        public Gerente [ ] gerentes ;
        public TrabajaRol [ ] trabajarols ;
        public Empleado [ ] empleados ;
        public TrabajaRol reclutar ( Empleado emp )
            {
            }
    }
}
''')#Parse devuelve el resultado de la ultima funcion que se redujo (recordar que se estaba haciendo un parser ascendente)
